#ifndef __KMER_COUNTER__
#define __KMER_COUNTER__

#include "FastaReader.h"
#include "Global.h"
#include "Kmer.h"
//#include "SparseMapWrapper.h"
#include "HashTree.h"
//#include SPARSEHASHMAP_H
using namespace std;
//using google::sparse_hash_map;
//using GOOGLE_NAMESPACE::SparseMapWrapper;

class KmerCounter
{
public:
	struct IntNoLessThan: public unary_function<int, bool> {
		int m_threshold;
		IntNoLessThan(int threshold = 0): m_threshold(threshold) {	}
		bool operator()(int i) {
			return m_threshold <= i;
		}
	};

//	typedef SparseMapWrapper<CompressedKmer, int, hash_kmer, eq_kmer> CounterMap;
	typedef HashTree<int> CounterMap;
	typedef CounterMap::iterator iterator;
private:
	CounterMap m_allKmers; ///< A set of all encountered kmers to examine redundant kmers.
	int m_threshold;
	bool verbose;
	GCOUNT_T m_trustedCnt;
	size_t m_trustedCountArray[HASHTREE_SIZE];

public:
	/**
	 * 	Constructor. Read reads from reader and count for trusted number of kmers.
	 *
	 * @author	Tao Yu
	 * @date	2011/3/6
	 *
	 * @param [in]	reader	The reader.
	 * @param	KmerLength	  	Length of the kmer.
	 * @param threshold		Minimal coverage accepted.
	 */
	KmerCounter(AbstractReader& reader, int threshold); // must be reference or you will get error c2248 if fstream object exists
	~KmerCounter() {};

	iterator begin() {
		return m_allKmers.begin();
	}

	iterator end() {
		return m_allKmers.end();
	}
	/**
	 * 	Gets the number of all kmers.
	 *
	 * @author	Tao Yu
	 * @date	2011/3/7
	 *
	 * @return	The total number of trusted kmers.
	 */
	GCOUNT_T numOfAllKmers() { return m_allKmers.size(); };

	GCOUNT_T numTrusted() { return m_trustedCnt; }


	/**
	 * Get the number of trusted kmer in each bucket
	 * @return the counting array of all buckets
	 */
	size_t* bucketTrustedCount() {
		return m_trustedCountArray;
	}
};

#endif